package semantic.rules.walk

import syntax.CGrammar._
import syntax.CASTNode
import scala.collection.mutable.Buffer
import semantic.COperations._
import semantic.CDataTypes._
import utils.data.CTree
import java.util.UUID
import utils.CID

object CWalkRuleFunctionDefinition extends CWalkRule
{
    override val categories = CFunctionDefinition :: Nil

    override def post(node:CASTNode)(implicit tree:CTree[CASTNode], code:Buffer[String]) =
    {
        if (!node().lastChild.firstChild.is(_.category == CExpression) && !node().preLastChild.lastChild.firstChild.is(_.category == CExpression)) code += s"$PUSH $NULL"
        code += RET += END += s"""$PUSH "${if (node().firstChild().value == "_") "#" + UUID.randomUUID().toString + "-" + CID.long else node().firstChild().value}"""" += BIND
    }

    override def pre(node:CASTNode)(implicit tree:CTree[CASTNode], code:Buffer[String]) =
    {
        var prmtrs = 0

        def walk(node:CASTNode)(implicit tree:CTree[CASTNode], code:Buffer[String]):Unit = node().children foreach (n => n.category match
        {
            case CFunctionParameter =>
                if (node().secondChild.is(_.category == CFunctionParameter)) walk(node().secondChild())
                code += s"""$PUSH "${n().lastChild().value}""""
                prmtrs += 1
            case _ => ()
        })

        walk(node)

        code += s"""$PUSH $prmtrs"""
        code += FUNC
    }
}
